from typing import List, Optional

from pydantic import BaseModel, UUID4, field_validator

from base.base_schemas import BaseOutSchema, BaseEditSchema, BaseFilterSchema
from .models import ArticleStatus


class TagBase(BaseModel):
    name: str


class TagEditSchema(TagBase, BaseEditSchema):
    pass


class TagOutSchema(TagBase, BaseOutSchema):
    pass


class CategoryBase(BaseModel):
    name: str
    short_name: str
    parent_id: Optional[UUID4] = None


class CategoryEditSchema(CategoryBase, BaseEditSchema):
    pass


class CategoryOutSchema(CategoryBase, BaseOutSchema):
    children: Optional[List["CategoryOutSchema"]] = None


class CategoryOutWithoutChildrenSchema(CategoryBase, BaseOutSchema):
    pass


class CategoryOutSchemaWithoutChildren(CategoryBase, BaseOutSchema):
    pass


class ArticleBase(BaseModel):
    title: str
    content: str
    cover: Optional[str] = None
    cover_hash: Optional[str] = None
    top: bool = False
    status: ArticleStatus = ArticleStatus.PUBLISHED
    views: int = 0
    keywords: Optional[str] = None
    description: Optional[str] = None
    password: Optional[str] = None


class ArticleEditSchema(ArticleBase, BaseEditSchema):
    tag_ids: Optional[List[UUID4]] = None
    category_id: UUID4


class ArticleOutSchema(ArticleBase, BaseOutSchema):
    category: CategoryOutSchemaWithoutChildren
    category_id: UUID4
    tags: Optional[List[TagOutSchema]] = None
    tag_ids: Optional[List[UUID4]] = None

    @classmethod
    @field_validator("tag_ids", mode="before")
    def set_tag_ids(cls, v, info):
        if "tags" in info.data and info.data["tags"]:
            return [tag.id for tag in info.data["tags"]]
        return v or None


class ThoughtOutSchema(BaseOutSchema):
    content: str


class ThoughtEditSchema(BaseEditSchema):
    content: str


class ArticleFilterSchema(BaseFilterSchema):
    title: Optional[str] = None
    content: Optional[str] = None
    category: Optional[UUID4] = None
    status: Optional[ArticleStatus] = None
    tags: Optional[List[UUID4]] = None


class TagFilterSchema(BaseFilterSchema):
    name: Optional[str] = None


class CategoryFilterSchema(BaseFilterSchema):
    name: Optional[str] = None
    short_name: Optional[str] = None


CategoryOutSchema.model_rebuild()
